#[must_use]
pub fn retire_time(time: &str, tp: &str) -> String {
    let (year, month) = parse_ym(time).unwrap();

    let retirement = match tp {
        "男职工" => solve(year, month, 1965, 1976, 60, 4),
        "原法定退休年龄55周岁女职工" => solve(year, month, 1970, 1981, 55, 4),
        "原法定退休年龄50周岁女职工" => solve(year, month, 1975, 1984, 50, 2),
        _ => panic!("Unknown type"),
    };

    format!(
        "{}-{:>02},{},{}",
        retirement.retire_year,
        retirement.retire_month,
        (retirement.retire_age * 100.).round() / 100.,
        retirement.delay_months
    )
}

fn parse_ym(time: &str) -> Result<(u32, u32), ()> {
    // yyyy-mm

    if time.len() != 7 {
        return Err(());
    }

    if time.as_bytes()[4] != b'-' {
        return Err(());
    }

    let year = time[0..4].parse::<u32>().map_err(|_| ())?;
    let month = time[5..7].parse::<u32>().map_err(|_| ())?;

    if !(1950..=2100).contains(&year) {
        return Err(());
    }

    if !(1..=12).contains(&month) {
        return Err(());
    }

    Ok((year, month))
}

#[derive(Debug)]
struct Retirement {
    retire_year: u32,
    retire_month: u32,
    retire_age: f64,
    delay_months: u32,
}

fn solve(
    year: u32,
    month: u32,
    start_year: u32,
    end_year: u32,
    age: u32,
    interval: u32,
) -> Retirement {
    if year < start_year {
        return Retirement {
            retire_year: year + age,
            retire_month: month,
            retire_age: f64::from(age),
            delay_months: 0,
        };
    }

    if year > end_year {
        let delay_months = (end_year - start_year + 1) * 12 / interval;
        let retire_age = age + delay_months / 12;
        return Retirement {
            retire_year: year + retire_age,
            retire_month: month,
            retire_age: f64::from(retire_age),
            delay_months,
        };
    }

    let month_diff = (year - start_year) * 12 + month - 1;
    let delay_months = (month_diff + interval) / interval;

    let m = month + delay_months;
    let retire_year = (year + age) + (m - 1) / 12;
    let retire_month = (m - 1) % 12 + 1;
    let retire_age = f64::from(age) + f64::from(delay_months) / 12.0;

    Retirement {
        retire_year,
        retire_month,
        retire_age,
        delay_months,
    }
}
